package com.zhrenjie04.alex.core;

import java.lang.annotation.Annotation;
import java.util.Arrays;

import javax.servlet.http.HttpServletResponse;

import org.springframework.core.MethodParameter;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;
/**
 * @author 张人杰
 */
public class AlexJsonReturnHandler implements HandlerMethodReturnValueHandler {

	@Override
	public boolean supportsReturnType(MethodParameter returnType) {
		boolean flag = returnType.getMethodAnnotation(ResponseJsonBody.class) != null
				|| returnType.getMethodAnnotation(ResponseJsonBodyWithFilters.class) != null;
		return flag;
	}

	@Override
	public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer,
			NativeWebRequest webRequest) throws Exception {
		HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
		Annotation[] annos = returnType.getMethodAnnotations();
		AlexJsonSerializer jsonSerializer = new AlexJsonSerializer();
		jsonSerializer.beginAddFilter();
		Arrays.asList(annos).forEach(a -> {
			if (a instanceof ResponseJsonBody) {
				ResponseJsonBody json = (ResponseJsonBody) a;
				jsonSerializer.filter(json.type(), json.include(), json.filter());
			}
			if (a instanceof ResponseJsonBodyWithFilters) {
				ResponseJsonBodyWithFilters jsonFilters = (ResponseJsonBodyWithFilters) a;
				for (ResponseJsonBody json : jsonFilters.value()) {
					jsonSerializer.filter(json.type(), json.include(), json.filter());
				}
			}
		});
		jsonSerializer.endAddFilter();
		response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
		String json = jsonSerializer.toJson(returnValue);
		if (returnValue instanceof JsonResult) {
			JsonResult result = (JsonResult) returnValue;
			if (result.getStatus() != HttpStatus.OK.value()) {
				response.sendError(result.getStatus(), result.getMessage());
			}
		}
		response.getWriter().write(json);
		response.getWriter().flush();
		mavContainer.setRequestHandled(true);
	}
}
